"use strict";

import topology from "./topology";
import compactor from "./compactor";

export default preprocess;
function preprocess(graph, options) {
    options = options || {};
    var weightFn =
            options.weightFn ||
            function defaultWeightFn(a, b) {
                return turf.distance(turf.point(a), turf.point(b));
            },
        topo;

    if (graph.type === "FeatureCollection") {
        // Graph is GeoJSON data, create a topology from it
        topo = topology(graph, options);
    } else if (graph.edges) {
        // Graph is a preprocessed topology
        topo = graph;
    }

    graph = topo.edges.reduce(
        function buildGraph(g, edge, i, es) {
            var a = edge[0],
                b = edge[1],
                props = edge[2],
                w = weightFn(topo.vertices[a], topo.vertices[b], props),
                makeEdgeList = function makeEdgeList(node) {
                    if (!g.vertices[node]) {
                        g.vertices[node] = {};
                        if (options.edgeDataReduceFn) {
                            g.edgeData[node] = {};
                        }
                    }
                },
                concatEdge = function concatEdge(startNode, endNode, weight) {
                    var v = g.vertices[startNode];
                    v[endNode] = weight;
                    if (options.edgeDataReduceFn) {
                        g.edgeData[startNode][endNode] = options.edgeDataReduceFn(options.edgeDataSeed, props);
                    }
                };

            if (w) {
                makeEdgeList(a);
                makeEdgeList(b);
                if (w instanceof Object) {
                    if (w.forward) {
                        concatEdge(a, b, w.forward);
                    }
                    if (w.backward) {
                        concatEdge(b, a, w.backward);
                    }
                } else {
                    concatEdge(a, b, w);
                    concatEdge(b, a, w);
                }
            }

            if (i % 1000 === 0 && options.progress) {
                options.progress("edgeweights", i, es.length);
            }

            return g;
        },
        { edgeData: {}, vertices: {} }
    );

    var compact = compactor.compactGraph(graph.vertices, topo.vertices, graph.edgeData, options);

    return {
        vertices: graph.vertices,
        edgeData: graph.edgeData,
        sourceVertices: topo.vertices,
        compactedVertices: compact.graph,
        compactedCoordinates: compact.coordinates,
        compactedEdges: options.edgeDataReduceFn ? compact.reducedEdges : null
    };
}
